import * as crypto from 'crypto';
import { IncomingMessage } from 'http';
import { getHttpQuery } from './http';

export function gitee(req: IncomingMessage, secret = ''): boolean {
  const query = getHttpQuery(req);
  const gtoken = req.headers['x-gitee-token'];

  // 签名秘钥
  if (query.sign && query.timestamp) {
    if (Math.abs(Date.now() - query.timestamp) < 3600000) {
      const token = crypto.createHmac('sha256', secret).update(`${query.timestamp}\n${secret}`).digest('base64');
      return token === gtoken;
    }
  }
  // webhook 密码
  else {
    return secret === gtoken;
  }
  return false;
}

export function github(req: IncomingMessage, secret = '', rawBody: string): boolean {
  const token = 'sha1=' + crypto.createHmac('sha1', secret).update(rawBody).digest('hex');
  return token === req.headers['x-hub-signature'];
}

// gitlab, gogs, gitea
export function others(req: IncomingMessage, secret = '', rawBody: string): boolean {
  let xtoken = '';
  for (const key in req.headers) {
    if (/^x-[\da-z-]+-(token)|(signature)$/i.test(key)) {
      const v = req.headers[key];
      xtoken = typeof v === 'string' ? v : '';
      break;
    }
  }
  if (xtoken === secret) {
    return true;
  }

  const token = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return token === xtoken;
}

export default function (req: IncomingMessage, secret = '', rawBody: string): boolean {
  if (req.headers['x-gitee-token']) {
    return gitee(req, secret);
  } else if (req.headers['x-hub-signature']) {
    return github(req, secret, rawBody);
  } else {
    return others(req, secret, rawBody);
  }
}